﻿using Microsoft.Extensions.DependencyInjection;
using System;
using System.Linq;
using System.Threading.Tasks;
using XUCore.Extensions;
using XUCore.WeChat.Enterprise.Apis.Suite;

namespace XUCore.WeChat.Enterprise
{
    /// <summary>
    /// 企业微信代开发 ticket管理器
    /// </summary>
    public class EnterpriseWeChatSuiteTicketManager : IEnterpriseWeChatSuiteTicketManager
    {
        private readonly EnterpriseWeChatFuncs weChatFuncs;
        private readonly IEnterpriseSuiteApi enterpriseSuiteApi;
        /// <summary>
        /// 企业微信js ticket管理器
        /// </summary>
        /// <param name="weChatFuncs"></param>
        /// <param name="serviceProvider"></param>
        public EnterpriseWeChatSuiteTicketManager(EnterpriseWeChatFuncs weChatFuncs, IServiceProvider serviceProvider)
        {
            this.weChatFuncs = weChatFuncs;
            this.enterpriseSuiteApi = serviceProvider.GetRequiredService<IEnterpriseSuiteApi>();
        }
        /// <summary>
        /// 写入ticket，缓存存储
        /// </summary>
        /// <param name="suiteId"></param>
        /// <param name="suiteTicket"></param>
        public virtual void SetTicket(string suiteId, string suiteTicket)
        {
            weChatFuncs?.CacheEnterpriseWeChatSuiteTicket(suiteId, suiteTicket);
        }

        /// <summary>
        /// 获取永久Secret
        /// </summary>
        /// <param name="suiteId"></param>
        /// <param name="authCode">临时授权码，会在授权成功时附加在redirect_uri中跳转回第三方服务商网站，或通过授权成功通知回调推送给服务商。长度为64至512个字节</param>
        /// <returns></returns>
        public virtual async Task<SuiteEnterpriseInfo> GetPermanentAsync(string suiteId, string authCode)
        {
            var opt = weChatFuncs.GetEnterpriseWeChatOptions();

            var suite = opt.FirstOrDefault(c => c.SuiteId == suiteId);

            if (suite == null)
                throw new WeChatSdkException($"SuiteId “{suiteId}” 配置不存在");

            var ticket = weChatFuncs.GetEnterpriseWeChatSuiteTicket(suiteId);

            if (ticket.IsEmpty())
                throw new WeChatSdkException($"SuiteTicket 不存在，请到服务商后台模板处刷新Ticket");

            var token = await enterpriseSuiteApi.GetSuiteTokenAsync(new SuiteTokenInput
            {
                suite_id = suite.SuiteId,
                suite_secret = suite.SuiteSecret,
                suite_ticket = ticket
            });

            var permanentCode = await enterpriseSuiteApi.GetPermanentCodeAsync(token.suite_access_token, new PermanentCodeInput
            {
                auth_code = authCode
            });

            return new SuiteEnterpriseInfo
            {
                CorpId = permanentCode.auth_corp_info.corpid,
                CorpName = permanentCode.auth_corp_info.corp_name,
                AgentId = permanentCode.auth_info.agent.FirstOrDefault().agentid,
                AgentSecret = permanentCode.permanent_code,
                Detail = permanentCode
            };
        }
    }
    /// <summary>
    /// 企业微信代开发 ticket管理器
    /// </summary>
    public interface IEnterpriseWeChatSuiteTicketManager
    {
        /// <summary>
        /// 写入ticket，缓存存储
        /// </summary>
        /// <param name="suiteId"></param>
        /// <param name="suiteTicket"></param>
        void SetTicket(string suiteId, string suiteTicket);
        /// <summary>
        /// 获取永久Secret
        /// </summary>
        /// <param name="suiteId"></param>
        /// <param name="authCode">临时授权码，会在授权成功时附加在redirect_uri中跳转回第三方服务商网站，或通过授权成功通知回调推送给服务商。长度为64至512个字节</param>
        /// <returns></returns>
        Task<SuiteEnterpriseInfo> GetPermanentAsync(string suiteId, string authCode);
    }

    /// <summary>
    /// 待开发获取的配置信息
    /// </summary>
    public class SuiteEnterpriseInfo
    {
        /// <summary>
        /// 企业ID，获取方式参考：术语说明-corpid <see href="https://developer.work.weixin.qq.com/document/path/90665#corpid"/>
        /// </summary>
        public string CorpId { get; set; }

        /// <summary>
        /// 企业简称
        /// </summary>
        public string CorpName { get; set; }

        /// <summary>
        /// 授权应用Id，授权的应用信息，注意是一个数组，但仅旧的多应用套件授权时会返回多个agent，对新的单应用授权，永远只返回一个agent
        /// </summary>
        public int AgentId { get; set; }

        /// <summary>
        /// 授权应用Secret
        /// </summary>
        public string AgentSecret { get; set; }

        /// <summary>
        /// 返回的详细数据
        /// </summary>
        public PermanentCodeApiResult Detail { get; set; }
    }
}
